# -*- encoding: utf-8 -*-
'''
@File    :   log_calc.py
@Time    :   2024/06/25
@Author  :   Han Xiao
@Brief   :   计算横向偏差的均值和标准差
'''
import re
import argparse
from datetime import datetime
import matplotlib.pyplot as plt
import math

def remove_outliers(data):
    outliers_count = 0
    filtered_data = [data[0]]  # 始终保留第一个数据点
    last_value = data[0]
    for value in data[1:]:
        if abs(value - last_value) > 0.5:
            outliers_count += 1  # 增加异常点计数
        else:
            filtered_data.append(value)
        last_value = value
    return filtered_data, outliers_count

# 定义命令行参数(LOG文件路径 & 解析关键字)
parser = argparse.ArgumentParser()
parser.add_argument('-k','--keys', nargs='+', help='关键字列表 有空格 分割，使用引号,如果包含冒号，将冒号也搞过来')
parser.add_argument('-l','--log', help='LOG 文件路径，使用绝对路径吧')
parser.add_argument('-f','--format', default=1, help='默认为1表示原智耘log格式, 2表示新智耘格式' )
args = parser.parse_args()

if args.keys:
    key_msgs = args.keys
else:
    parser.print_help()
    exit()

if args.log:
    log_path = args.log
else:
    parser.print_help()
    exit()

log_format = int(args.format)
# 关键字列表 有空格，如果包含冒号，将冒号也搞过来
# key_msgs = ['real_speed', 'set_target_imple:','forecast_radar_flag:']

# 定义正则表达式，用于匹配时间
time_pattern = re.compile(r'[IDE](\d{2})(\d{2}) (\d{2}):(\d{2}):(\d{2}).(\d{3}) (\d+) ')
if log_format == 2:
    time_pattern = re.compile(r'\[(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\.(\d{3})\]')

# 定义正则表达式，用于匹配关键信息（数字 or true or false）
patterns = []
for key_msg in key_msgs:
    pattern_key_msg = r'{}\s+([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?|true|false)'.format(key_msg)
    patterns.append(re.compile(pattern_key_msg))

# 打开log文件
with open(log_path, 'r') as f:
    lines = f.readlines()

# 初始化关键信息列表
key_info = [[] for _ in range(len(key_msgs))]

# 遍历每一行log信息,收集数据
for line in lines:
    # 匹配时间和关键信息
    time_match = time_pattern.match(line)
    for i, pattern in enumerate(patterns):
        key_info_match = pattern.search(line)
        if time_match and key_info_match:
            key_info_value = key_info_match.group(1)
            if key_info_value == 'true':
                key_info_value = 1
            elif key_info_value == 'false':
                key_info_value = 0
            else:
                key_info_value = float(key_info_value)
            key_info[i].append(key_info_value)

# 剔除异常值
filtered_key_info = []
outliers_counts = []
for key_values in key_info:
    filtered_values, outliers_count = remove_outliers(key_values)
    filtered_key_info.append(filtered_values)
    outliers_counts.append(outliers_count)

# 打印每组数据中的异常点个数
for key, outliers_count in zip(key_msgs, outliers_counts):
    print(f"{key} 的异常点个数: {outliers_count}")

# 计算每个关键字的绝对值均值
mean_values = {}
for key, key_values in zip(key_msgs, filtered_key_info):
    if key_values:
        abs_values = [abs(num) for num in key_values]
        mean = sum(abs_values) / len(abs_values) if abs_values else 0
        mean_values[key] = mean
    else:
        mean_values[key] = 0

for key, mean in mean_values.items():
    print(f"{key} 的均值（绝对值）: {mean:.5f}")

# 计算每个关键字的绝对值标准差
std_dev_values = {}
for key, key_values in zip(key_msgs, filtered_key_info):
    if key_values: 
        mean_abs = mean_values[key]
        sum_of_squares = sum((abs(x) - mean_abs) ** 2 for x in key_values)
        # 计算方差
        variance = sum_of_squares / (len(key_values) - 1)  # 使用n-1作为分母
        # 计算标准差
        std_dev = math.sqrt(variance)
        std_dev_values[key] = std_dev
    else:
        std_dev_values[key] = 0

# 打印每个关键字的绝对值标准差
for key, std_dev in std_dev_values.items():
    print(f"{key} 的标准差（绝对值）: {std_dev:.5f}")
